﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NewsMine.DomainObjects;
using NewsMine.Storage;
using LuceneWrap.Lib;
using Lucene.Net.Search;
using NewsMine.Storage.SQLite;
using System.IO;
using NewsDiscoveryEngine.Index;
using NewsMine.Utilities;

namespace NewsDiscoveryEngine
{
    public class FeedIndexSearcher
    {
        IndexStoreManagerOnFileSystem indexStoreMgr = new IndexStoreManagerOnFileSystem();
        private static FeedIndexSearcher feedIndexSearcher;
        private LuceneWrap.Lib.LuceneSearcher searcher;
        string folder;
        string stagingFolder;


        string sqliteFeedStoreFilePath;
        SQLiteFeedStoreHelper sqliteFeedStoreHelper;


        public SQLiteFeedStoreHelper SQLiteFeedStoreHelper
        {
            get
            {
                return sqliteFeedStoreHelper;
            }
        }

        private FeedIndexSearcher()
        {


            folder = indexStoreMgr.GetIndexStoreFolderByName(IndexerConstants.indexFolderName);


            sqliteFeedStoreFilePath = Path.Combine(folder + "\\SqliteFeedStore\\sqliteFeedStore.db");
            sqliteFeedStoreHelper = new SQLiteFeedStoreHelper(sqliteFeedStoreFilePath);


            searcher = new LuceneWrap.Lib.LuceneSearcher(folder);

        }



        private void MakeSureIndexSearcherIsOpened()
        {
            try
            {
                if (searcher == null)
                    searcher = new LuceneSearcher(folder);
                else
                {
                    if (searcher.IndexSearcher.GetIndexReader().IsCurrent() == false)
                    {
                        searcher.Finalize();
                        searcher = new LuceneSearcher(folder);
                    }
                }
            }
            catch (System.IO.FileNotFoundException ioException)
            {
                if (ioException.Message.ToLower().Contains("no segments* file found") || ioException.Message.ToLower().Contains("this indexreader is closed"))
                {
                    if (searcher == null)
                        searcher = new LuceneSearcher(folder);
                }
            }
            catch (Exception ex)
            {
                if (ex.Message.ToLower().Contains("no segments* file found") || ex.Message.ToLower().Contains("this indexreader is closed"))
                {
                    if (searcher == null)
                        searcher = new LuceneSearcher(folder);
                }
            }
        }

        public static FeedIndexSearcher Instance
        {
            get
            {
                if (feedIndexSearcher == null)
                    feedIndexSearcher = new FeedIndexSearcher();
                feedIndexSearcher.MakeSureIndexSearcherIsOpened();
                return feedIndexSearcher;
            }
        }

        public List<FeedItem> GetFeedItemsByDomain(string domain)
        {
            MakeSureIndexSearcherIsOpened();

            //searcher.IndexSearcher.Search(

            return searcher.Search<FeedItem>("domain:" + "\"" + domain.ToLower() + "\"");
        }

        public List<FeedItem> GetFeedItemsByDomain(string domain, int pageNumber, int rowsPageNumber)
        {
            MakeSureIndexSearcherIsOpened();

            return searcher.GetResults<FeedItem>("domain:" + domain, pageNumber, rowsPageNumber);
        }

        public List<FeedItem> GetFeedItemsByQuery(string query, int pageNumber, int rowsPerPageNumber, out int totalRecordsMatched)
        {
            MakeSureIndexSearcherIsOpened();
            return searcher.GetResults<FeedItem>(query, pageNumber, rowsPerPageNumber, out totalRecordsMatched);
        }

        public List<FeedItem> GetFeedItemsByQueryOrderByLatest(string query, int pageNumber, int rowsPerPageNumber, out int totalRecordsMatched,bool orderByLatest)
        {
            MakeSureIndexSearcherIsOpened();
            return searcher.GetResultsAndSortByLatest<FeedItem>(query, pageNumber, rowsPerPageNumber, out totalRecordsMatched,orderByLatest);
        }

        public List<FeedItem> GetFeedItemsByIDRange(long min, long max, int pageNumber, int rowsPerPageNumber, out int totalRecordsMatched)
        {
            MakeSureIndexSearcherIsOpened();
            return searcher.TestNumericSearch<FeedItem>(min, max, pageNumber, rowsPerPageNumber, out totalRecordsMatched);
        }

      

        public List<FeedItem> GetFeedItemsByDomainAndCategory(string domain, string category)
        {
            MakeSureIndexSearcherIsOpened();

            return searcher.Search<FeedItem>("domain:" + "\"" + domain.ToLower() + "\" AND category:" + "\"" + category.ToLower() + "\"");
        }

        public List<FeedItem> GetFeedItemsByQuery(string query)
        {
            MakeSureIndexSearcherIsOpened();

            return searcher.Search<FeedItem>(query);
        }

        public FeedItem GetFeedById(long id)
        {
            List<FeedItem> feeds = new List<FeedItem>();

            try
            {
                feeds = GetFeedItemsByQuery("id:" + id.ToString());
            }
            catch (Exception ex)
            {
                TempLogger.Log("Error while getting feed by id", ex);

                System.Threading.Thread.Sleep(200);

                try
                {
                    feeds = GetFeedItemsByQuery("id:" + id.ToString());


                }
                catch
                {
                    return null;
                }
            }

            if (feeds != null && feeds.Count > 0)
                return feeds[0];
            else
                return null;
        }

        public List<FeedItem> GetAllFeeds()
        {
            MakeSureIndexSearcherIsOpened();

            return searcher.GetAll<FeedItem>();
        }

    }
}
